var TermsData;

function myCompareFunction(a, b) {
	return a.coschTitle().toLowerCase() > b.coschTitle().toLowerCase() ? 1 : -1;
};
function mySubjectCompareFunction(a, b) {
	return a.subjectId.subjectName().toLowerCase() > b.subjectId.subjectName().toLowerCase() ? 1 : -1;
};

function myGradeCompareFunction(a, b) {
	return a.gradeTitle().toLowerCase() > b.gradeTitle().toLowerCase() ? 1 : -1;
};

/**
 * BO Tab4 ViewModel
 */
var myMainSubjectViewModel = function() {
	var self = this;
	rootSelfTab4 = this;

	self.UsedSubjectArray = ko.observableArray([]);
	self.isEditMode = ko.observable(isEditMode);

	/**
	 * mappedGradesVOarr: will keep all the grades to map the Subjects and populate
	 * mappedGradeObj: will keep the selected Grade for mapping.
	 */
	self.mappedGradesVOarr = ko.observableArray([]);
	self.mappedGradeObj = ko.observable();
	self.mappedGradeID = ko.observable();

	self.selectedTabID = ko.observable('tabs-1');

	self.isSubjectsRendered = ko.observable(false);
	self.subjectsArrayLoadedCount = ko.observable(0);

	self.subjectsArrayLoadedCount.subscribe(function(newValue) {
		if (newValue == 3) {
			//console.log("loding Sequence Render 0000 all Subjects Loaded Now :: ");
			self.applyCnageToUI();
		};
	});

	self.applyCnageToUI = function(calleName) {

		/**
		 *Done: Disable the Check boxes
		 */

		if (self.subjectsArrayLoadedCount() == 3 && self.isSubjectsRendered()) {
			// console.log("if loding Sequence Render select') 			:: ", $('.floorContentScholastic.disabledSelect select').length);
			// console.log("if loding Sequence Render input[type=text]') 	:: ", $('.floorContentScholastic.disabledSelect input[type=text]').length);
			// console.log("if loding Sequence Render a') 				:: ", $('.floorContentScholastic.disabledSelect a').length);
			//
			// console.log("if loding Sequence Render $('#dialog-define input[type=checkbox]') :: ", $('#dialog-define input[type=checkbox]').length);
			// console.log("if loding Sequence Render applyCnageToUI :: ");
			//
			// console.log("********** 11 if loding Sequence Render 555 subjectsArrayLoadedCount() : isSubjectsRendered() :: ", self.subjectsArrayLoadedCount(), self.isSubjectsRendered());

			if (tab4SubjectViewModel.isEditMode()) {

			} else {
				console.log("********** 22 if loding Sequence Render 555 subjectsArrayLoadedCount() : isSubjectsRendered() :: ", self.subjectsArrayLoadedCount(), self.isSubjectsRendered());

				// $('#dialog-define #subjectImportButton').css("display","none");
				$('.floorContentScholastic.disabledSelect select').prop("disabled", "disabled");
				$('.floorContentScholastic.disabledSelect input[type="text"]').prop("disabled", "disabled");
				$('.floorContentScholastic.disabledSelect a').css("display", "none");
				/**
				 *Done: Disable the Check boxes
				 */
				$('#dialog-define input[type=checkbox]').prop("disabled", "disabled");
				$('#dialog-define .css-labelSubjects').css("cursor", "default");
				/**
				 *Done: Disable the Select in the CoCurricular Tab
				 */
				$('#dialog-define .subjectCoScholastic.disabledSelect select').prop("disabled", "disabled");

			};
		};

	};
	self.GradesVOarr = ko.observableArray([]);
	self.TermsData = ko.observableArray([]);
	self.SubjectListVOarr = ko.observableArray([]);
	self.myOptions = [{
		name : 'Compulsory',
		id : false
	}, {
		name : 'Optional',
		id : true
	}];

	self.mySingleOptions = [{
		name : 'Compulsory',
		id : false
	}];

	// all Grades list
	self.getMappedGradesByAcadUrl = baseOperationUrl + "getMappedGradesByAcad&aypId=" + aypId;

	// all Grades list
	self.getSecGradesUrl = baseOperationUrl + "getSecGrades&sectionId=" + sectionId;

	//all subjects list
	self.getSchoolSubjectsUrl = baseOperationUrl + "getSchoolSubjects";

	//all terms
	self.getSecTermsUrl = baseOperationUrl + "getSecTerms&sectionId=" + sectionId;

	//all subjects and sub subjects for Scholastics
	self.getSecGradeSubjectsUrl = baseOperationUrl + "getSecGradeSubjects&sectionId=";
	//all subjects and sub subjects for CoScholastics
	self.getSecCoScholasticsUrl = baseOperationUrl + "getSecCoScholastics&sectionId=";
	//all subjects and sub subjects for CoScholastics
	self.getSecCoCurricularsUrl = baseOperationUrl + "getSecCoCurriculars&sectionId=";

	//save it
	self.saveSecGradeSubjectsUrl = baseOperationUrl + "saveSecGradeSubjects";

	this.itemToAdd = ko.observable();
	this.itemParentToAdd = ko.observable();

	this.assessItemToAdd = ko.observable();
	this.assessItemParentToAdd = ko.observable();

	//hold the currently selected item
	this.selectedItem = ko.observable();

	//make edits to a copy
	this.selectedGradeVO = ko.observable();
	this.itemForEditing = ko.observable();

	this.defineGrade = this.defineGrade.bind(this);
	this.selectItem = this.selectItem.bind(this);
	this.acceptItemSubjects = this.acceptItemSubjects.bind(this);
	this.revertItem = this.revertItem.bind(this);

	this.afterDefineScholasticRender = function() {
		console.log("afterDefineScholasticRender :: ");

	};

	/////////////////////////////////
	self.onMappedGradeChange = function(t, e, s) {
		var selectedIndex = s.currentTarget.selectedIndex - 1;
		var selectedVO = self.mappedGradesVOarr()[selectedIndex];
		var tempObj = {
			ceGradeId : selectedVO.ceGradeId(),
			sectionId : selectedVO.sectionId()
		};
		self.mappedGradeObj(tempObj);
	};
	self.onImportGradeAccept = function() {
		self.subjectsArrayLoadedCount(2);
		//TODO:
		self.closeImportPopup();

		console.log("self.mappedGradeObj() :: ", self.mappedGradeObj());

		//return;
		var myFullGetSecGradeSubjectsUrl = self.getSecGradeSubjectsUrl + self.mappedGradeObj().sectionId + '&ceGradeId=' + self.mappedGradeObj().ceGradeId;
		var myFullGetSecCoScholasticsUrl = self.getSecCoScholasticsUrl + self.mappedGradeObj().sectionId + '&ceGradeId=' + self.mappedGradeObj().ceGradeId;
		var myFullGetSecCoCurricularsUrl = self.getSecCoCurricularsUrl + self.mappedGradeObj().sectionId + '&ceGradeId=' + self.mappedGradeObj().ceGradeId;

		/**
		 * TODO: import only Scholastics not CoScho or CoCurr
		 */
		self.loadSubjectsScholastics(myFullGetSecGradeSubjectsUrl, true);

		//self.loadSubjectsCoScholastics(myFullGetSecCoScholasticsUrl);
		//self.loadSubjectsCoCurricular(myFullGetSecCoCurricularsUrl);
	};

	self.isImportPopupOpen = ko.observable(false);
	self.openImportPopup = function() {
		getMappedGradesByAcad();
		self.isImportPopupOpen(true);
	};
	self.closeImportPopup = function() {
		self.isImportPopupOpen(false);
	};
	self.titleImportPopup = ko.observable();

	/////////////////////////////////

	self.isOpen = ko.observable(false);
	self.open = function() {
		this.isOpen(true);
	};
	self.close = function() {
		this.isOpen(false);
	};
	self.mytitle = ko.observable();

	/////////////////////////////////////////
	self.lastSavedJson = ko.observable("");
	/* --------------------------------------- BO hide Unhide tabs on the basis of Availability */

	/**
	 *Check and Store if CoScholastic is there.
	 *
	 */
	this.GradesVOarr.hasCoCurr = ko.computed(function() {
		var hasScholastic = false;
		if (self.selectedGradeVO()) {
			if (self.selectedGradeVO().SubjectCoCurrVOarr().length > 0) {
				hasScholastic = true;
			} else {
				hasScholastic = false;
			}
		}

		console.log("hasCoCurr :: ", hasScholastic);

		return hasScholastic;

	}, this);
	/**
	 *Check and Store if CoScholastic is there.
	 *
	 */
	this.GradesVOarr.hasCoScholastic = ko.computed(function() {
		var hasScholastic = false;
		if (self.selectedGradeVO()) {
			if (self.selectedGradeVO().SubjectCoSchoVOarr().length > 0) {
				hasScholastic = true;
			} else {
				hasScholastic = false;
			}
		}
		console.log("hasCoScholastic :: ", hasScholastic);
		return hasScholastic;

	}, this);

	/* --------------------------------------- EO hide Unhide tabs on the basis of Availability */

	self.onSaved = function(edited) {
		var saveDataStr = JSON.stringify(ko.toJS(edited.SubjectVOarr), null, 2);

		//join the 2 array
		var coScho_coCurr_arr = edited.SubjectCoSchoVOarr.concat(edited.SubjectCoCurrVOarr);
		var coScho_coCurr_str = JSON.stringify(ko.toJS(coScho_coCurr_arr), null, 2);

		showLoader(true, TYPE_SAVING);
		saveScholasticsDataToServer(saveDataStr, coScho_coCurr_str);
		//saveCoScholasticsDataToServer(coScho_coCurr_str, saveDataStr);

		//self.lastSavedJson(JSON.stringify(ko.toJS(self.SubjectVOarr), null, 2));

	};

	/**
	 *Load the Co Curricular ones
	 *
	 * 29Aug2013
	 */
	self.loadSubjectsCoCurricular = function(myFullUrl) {
		console.log("loadSubjectsCoCurricular myFullUrl :\n", myFullUrl);
		var jqxhr = $.getJSON(myFullUrl, {
			returnformat : 'json'
		}, function(allData) {
			//console.log("loadSubjectsCoCurricular allData :: ", allData)
			var mappedData = jQuery.map(allData, function(item) {
				return new SubjectCoSchoVO(item);
			});
			self.selectedGradeVO().SubjectCoCurrVOarr(mappedData);
			//self.selectedGradeVO().SubjectCoCurrVOarr.sort(myCompareFunction);
		});

		/** ----------------------------------------- Event Listeners */
		jqxhr.done(function(allData) {
			/* Working the Object Access */
			console.log("loadSubjectsCoCurricular second success", allData);
		});
		jqxhr.fail(function() {
			console.log("error myMain Subject ViewModel tab4 loadSubjectsCoCurricular ");
		});
		jqxhr.always(function() {
			//console.log("complete");
		});
		jqxhr.complete(function() {
			//console.log("loding Sequence Render 3 loadSubjectsCoCurricular self.subjectsArrayLoadedCount() :: ", self.subjectsArrayLoadedCount());
			self.subjectsArrayLoadedCount(self.subjectsArrayLoadedCount() + 1);
			/**
			 *
			 * call init after tab is changed.
			 */
			//Custom.init();
		});
		/** ----------------------------------------- End Event Listeners */
	};
	self.loadSubjectsCoScholastics = function(myFullUrl) {
		console.log("loadSubjectsCoScholastics myFullUrl :\n", myFullUrl);
		var jqxhr = $.getJSON(myFullUrl, {
			returnformat : 'json'
		}, function(allData) {
			//console.log("loadSubjectsCoScholastics allData :: ", allData)
			var mappedData = jQuery.map(allData, function(item) {
				return new SubjectCoSchoVO(item);
			});
			self.selectedGradeVO().SubjectCoSchoVOarr(mappedData);
			//self.selectedGradeVO().SubjectCoSchoVOarr.sort(myCompareFunction);
		});

		/** ----------------------------------------- Event Listeners */
		jqxhr.done(function(allData) {
			/* Working the Object Access */
			//console.log("loadSubjectsCoScholastics second success", allData);
		});
		jqxhr.fail(function() {
			console.log("error myMain Subject ViewModel tab4 loadSubjectsCoScholastics ");
		});
		jqxhr.always(function() {
			//console.log("complete");
		});
		jqxhr.complete(function() {
			//console.log("loding Sequence Render 2 loadSubjectsCoScholastics self.subjectsArrayLoadedCount() :: ", self.subjectsArrayLoadedCount());
			self.subjectsArrayLoadedCount(self.subjectsArrayLoadedCount() + 1);
			/**
			 *
			 * call init after tab is changed.
			 */
			//Custom.init();

		});
		/** ----------------------------------------- End Event Listeners */
	};
	// this will be called from Define Link
	self.loadSubjectsScholastics = function(myFullUrl, forMapping) {
		console.log("forMapping Scholastics:\n", forMapping);
		console.log("myFullUrl Scholastics:\n", myFullUrl);
		var jqxhr = $.getJSON(myFullUrl, {
			returnformat : 'json'
		}, function(allData) {
			console.log("allData loadSubjectsScholastics:: ", allData);
			var mappedData = jQuery.map(allData, function(item) {
				//SubjectVO new 1
				return new SubjectVO(item, "", forMapping);
			});
			self.selectedGradeVO().SubjectVOarr(mappedData);
			//self.selectedGradeVO().SubjectVOarr.sort(mySubjectCompareFunction);
		});

		/** ----------------------------------------- Event Listeners */
		jqxhr.done(function(allData) {
			/* Working the Object Access */
			console.log("second success loadSubjectsScholastics ", allData);
		});
		jqxhr.fail(function() {
			console.log("error myMain Subject ViewModel tab4 loadSubjects");
		});
		jqxhr.always(function() {
			//console.log("complete");
		});
		jqxhr.complete(function() {
			self.subjectsArrayLoadedCount(self.subjectsArrayLoadedCount() + 1);
			//console.log("loding Sequence Render 1 loadSubjectsScholastics self.subjectsArrayLoadedCount() :: ", self.subjectsArrayLoadedCount());
		});
		/** ----------------------------------------- End Event Listeners */
	};

	self.init = function() {
		loadSubjectsList();
		//console.log("called init");
	};
	//Load list of Subjects also;
	//self.init();

	function loadSubjectsList() {
		showLoader(true, TYPE_LOADING);
		var jqxhr = $.getJSON(self.getSchoolSubjectsUrl, {
			returnformat : 'json'
		}, function(allData) {
			console.log("loadSubjectsList allData :: ", allData);
			var mappedData = jQuery.map(allData, function(item) {
				return new SubjectListVO(item);
			});
			//Done: Make it Global in the Model and access like Combo functionality.
			self.SubjectListVOarr(mappedData);
		});
		/** ----------------------------------------- Event Listeners */
		jqxhr.done(function(allData) {
			/* Working the Object Access */
			//console.log("second success", allData[0]);
			//console.log("second success self.selectedGradeVO() ", self.selectedGradeVO());
		});
		jqxhr.fail(function() {
			console.log("error loadSubjectsList Url :: ", self.getSchoolSubjectsUrl);
		});
		jqxhr.always(function() {
			//console.log("complete");
		});
		jqxhr.complete(function() {
			//console.log("second complete");
			//console.log("second complete self.selectedGradeVO() ", self.selectedGradeVO());
			loadTermsData();
		});
		/** ----------------------------------------- End Event Listeners */
	}

	function loadTermsData() {
		var jqxhr = $.getJSON(self.getSecTermsUrl, {
			returnformat : 'json'
		}, function(allData) {
			//console.log("allData :: ", allData)
			var mappedData = jQuery.map(allData, function(item) {
				//1 new term
				return new myTermVO(item);
			});
			//TODO: Make it Common.
			TermsData = mappedData;
			self.TermsData(mappedData);
		});
		/** ----------------------------------------- Event Listeners */
		jqxhr.done(function(allData) {
			/* Working the Object Access */
			//console.log("second success", allData[0]);
			//console.log("second success self.selectedGradeVO() ", self.selectedGradeVO());
		});
		jqxhr.fail(function() {
			console.log("error loadTermsData Url");
		});
		jqxhr.always(function() {
			//console.log("complete");
		});
		jqxhr.complete(function() {
			//console.log("second complete");
			//console.log("second complete self.selectedGradeVO() ", self.selectedGradeVO());
			//load the grades first to populate the Main View.
			loadGrades();
		});
		/** ----------------------------------------- End Event Listeners */
	}

	/**
	 * get all grades which has Subjects already and can be mapped to a new one.
	 *
	 */
	function getMappedGradesByAcad() {
		console.log("self.getMappedGradesByAcadUrl :: ", self.getMappedGradesByAcadUrl);
		var jqxhr = $.getJSON(self.getMappedGradesByAcadUrl, {
			returnformat : 'json'
		}, function(allData) {
			console.log("getMappedGradesByAcad allData :: ", allData);
			var mappedData = jQuery.map(allData, function(item) {
				return new GradeVO(item);
			});

			self.mappedGradesVOarr(mappedData);
			/**
			 *TODO Push all as a new Grade
			 */
		});
		/** ----------------------------------------- Event Listeners */
		jqxhr.done(function(allData) {
			/* Working the Object Access */
			console.log("second success getMappedGradesByAcad allData : ", allData);
		});
		jqxhr.fail(function() {
			console.log("error myMain SubjectView Model tab4 getMappedGradesByAcad");
		});
		jqxhr.always(function() {
			//console.log("complete");
		});
		jqxhr.complete(function() {
			//console.log("second complete");
			showLoader(false);
		});
		/** ----------------------------------------- End Event Listeners */
	}

	function loadGrades() {
		console.log("self.getSecGradesUrl :: ", self.getSecGradesUrl);
		var jqxhr = $.getJSON(self.getSecGradesUrl, {
			returnformat : 'json'
		}, function(allData) {
			//console.log("allData :: ", allData)
			var mappedData = jQuery.map(allData, function(item) {
				return new GradeVO(item);
			});
			self.GradesVOarr(mappedData);
			/**
			 *Commented as it will be already sorted from Server Side
			 */
			//self.GradesVOarr.sort(myGradeCompareFunction);
		});
		/** ----------------------------------------- Event Listeners */
		jqxhr.done(function(allData) {
			/* Working the Object Access */

			//console.log("second success loadGrades allData : ", allData);
		});
		jqxhr.fail(function() {
			console.log("error myMain SubjectView Model tab4 loadGrades");
		});
		jqxhr.always(function() {
			//console.log("complete");
		});
		jqxhr.complete(function() {
			console.log("loadGrades second complete");
			showLoader(false);
		});
		/** ----------------------------------------- End Event Listeners */
	}

};

ko.utils.extend(myMainSubjectViewModel.prototype, {
	//Prasanna
	//TODO for Define also
	defineGrade : function(item) {
		console.log("fun call >> not called ever defineGrade :: ");
		myTab4Mode = "defineSubject";
		this.selectedGradeVO(item);
		this.selectedItem(item);
		this.itemForEditing(new GradeVO(ko.toJS(item), myTab4Mode));
		this.itemParentToAdd = this.selectedGradeVO;
		//Prasanna
		this.open();
	},
	//select an item and make a copy of it for editing
	selectItem : function(item) {
		this.subjectsArrayLoadedCount(0);
		console.log("fun call >> selectItem :: ");
		myTab4Mode = "defineSubject";
		this.itemParentToAdd = this.selectedGradeVO;
		//set the item to be added for term
		this.itemToAdd = new GradeVO(ko.toJS(item), myTab4Mode);
		this.selectedGradeVO(this.itemToAdd);
		this.selectedItem(this.itemToAdd);
		this.itemForEditing(this.itemToAdd);

		this.mytitle("Subjects for " + item.gradeTitle());
		//console.log("this :: ", this)
		//console.log("item.ceGradeId() ======== :: ", item.ceGradeId())
		this.open();

		var myFullGetSecGradeSubjectsUrl = this.getSecGradeSubjectsUrl + sectionId + '&ceGradeId=' + item.ceGradeId();
		var myFullGetSecCoScholasticsUrl = this.getSecCoScholasticsUrl + sectionId + '&ceGradeId=' + item.ceGradeId();
		var myFullGetSecCoCurricularsUrl = this.getSecCoCurricularsUrl + sectionId + '&ceGradeId=' + item.ceGradeId();

		this.loadSubjectsScholastics(myFullGetSecGradeSubjectsUrl);
		this.loadSubjectsCoScholastics(myFullGetSecCoScholasticsUrl);
		this.loadSubjectsCoCurricular(myFullGetSecCoCurricularsUrl);

	},

	acceptItemSubjects : function(item) {
		console.log("fun call >> acceptItemSubjects :: ");
		var self = this;
		myTab4Mode = "save";
		//Prasanna
		var selected = this.selectedItem(), edited = ko.toJS(this.itemForEditing());

		//console.log("selected.coSch_isReadyForSave() 222 :: ", selected.coSch_isReadyForSave());
		//console.log("selected.sch_isReadyForSave() 111 :: ", selected.sch_isReadyForSave());
		var optional_isReadyForSave = selected.cosCurrOptional_isReadyForSave();

		if (!optional_isReadyForSave) {
			$("#dialog-SaveSubjects5").dialog("open");
			$("#dialog-SaveSubjects5 #cencel").click(function() {
				$("#dialog-SaveSubjects5").dialog("close");
			});
			return;
		};

		if (selected.sch_isReadyForSave()) {

			/**
			 *Check if has Valid Marks
			 */
			if (!selected.sch_isMarksValidated()) {
				$("#dialog-SaveSubjects6").dialog("open");
				$("#dialog-SaveSubjects6 #cencel").click(function() {
					$("#dialog-SaveSubjects6").dialog("close");
				});
				return;
			}
			/**
			 *Check if has DuplicateSubjects
			 */
			if (selected.sch_hasDuplicateSubjects()) {
				$("#dialog-SaveSubjects4").dialog("open");
				$("#dialog-SaveSubjects4 #cencel").click(function() {
					$("#dialog-SaveSubjects4").dialog("close");
				});
				return;
			}
			/**
			 *Check if only one subSubject is there
			 */
			if (!selected.sch_SubSubjectisReadyForSave()) {
				$("#dialog-SaveSubjects3").dialog("open");
				$("#dialog-SaveSubjects3 #cencel").click(function() {
					$("#dialog-SaveSubjects3").dialog("close");
				});
				return;
			}

			if (selected.coSch_isReadyForSave()) {
				//Save without popup

				//clean copy of edited
				//apply updates from the edited item to the selected item
				//TODO 1
				//selected.update(edited, myTab4Mode);
				self.onSaved(edited);
				self.close();

			} else {
				//popup 2 for having No CoScholastics.
				//Save if yes
				//Cancel

				$("#dialog-SaveSubjects1").dialog("open");
				$("#dialog-SaveSubjects1 #delete").click(function() {
					$("#dialog-SaveSubjects1").dialog("close");
					//TODO 1
					//selected.update(edited, myTab4Mode);

					self.onSaved(edited);
					self.close();
				});
				$("#dialog-SaveSubjects1 #cencel").click(function() {
					$("#dialog-SaveSubjects1").dialog("close");
				});
			}

		} else {
			//popup 1 for having No Scholastics.
			//No Save
			//Cancel

			$("#dialog-SaveSubjects2").dialog("open");
			$("#dialog-SaveSubjects2 #cencel").click(function() {
				$("#dialog-SaveSubjects2").dialog("close");
			});
		}
	},

	//just throw away the edited item and clear the selected observables
	revertItem : function() {
		console.log("fun call >> revertItem :: ");
		//Prasanna
		this.close();
		this.selectedItem(null);
		this.itemForEditing(null);
	}
});
// ====================================================================== EO new Model implementation //////////////
/**
 * EO Tab4 ViewModel
 */

// ====================================================================== BO new Model implementation //////////////
var TermsData;

var myTab4Mode = "addAssessment";

// new ones edited from Example
var myTermVO = function(data, forMapping) {
	this.termId = ko.observable();
	this.termTitle = ko.observable();

	this.termTitle.customTitle = ko.computed({
		read : function() {
			var resultReturn = false;
			resultReturn = this.termTitle() + " Marks";
			return resultReturn;
		},
		deferEvaluation : true //don’t evaluate until someone requests the value
	}, this);

	this.marks = ko.observable();
	//this.totalMarks = ko.observable();

	this.onValueChange = function(termVO, subjectVO, mark, xtra) {
		console.log("xtra ======= :: ", xtra);

		var myMark = mark;
		console.log("====================== myMark ======= :: ", myMark);
		var myTermID = termVO.termId();
		var mySubjectID = subjectVO.subjectId();
		var parentSubject;
		//loop through all subject and find the changed Parent Subject and make it Self.
		parentSubject = subjectVO;

		for (var t = 0; t < TermsData.length; t++) {
			//loop for All Subjects
			for (var s = 0; s < parentSubject.childSubs().length; s++) {
				var sub = parentSubject.childSubs()[s];
				var term = sub.terms()[t];
				var termMark = 0;
				if (term) {
					termMark = term.marks();

					if (term.termId() == myTermID) {

						//console.log("myMark ======= :: ", myMark);
						//console.log("myTermID ======= :: ", myTermID);
						if (sub.parentSubId() == mySubjectID) {
							//console.log("sameeeeeeeeee myTermID ======= :: ", myTermID);
							term.marks(myMark);
						} else {
							//console.log("termMark ======= :: ", termMark);
							//term.marks(myMark);
							//console.log("else termMark after ======= :: ", termMark);
						}
					}
				};

			};
		};

	};
	this.cache = function() {
	};
	this.update(data, forMapping);
};
//can pass fresh data to this function at anytime to apply updates or revert to a prior version
ko.utils.extend(myTermVO.prototype, {
	update : function(data, forMapping) {
		this.termId(data.termId || "");
		this.termTitle(data.termTitle || "");
		this.marks(data.marks || 0);
		if (forMapping) {
			this.marks(0);
		};
		//save off the latest data for later use
		this.cache.latestData = data;
	},
	revert : function() {
		this.update(this.cache.latestData);
	}
});

var GradeVO = function(data, mode) {
	var self = this;

	this.ceGradeId = ko.observable();
	this.coScholastics = ko.observable();
	this.coCurriculars = ko.observable();
	this.coreSubjects = ko.observable();
	this.optionalSubjects = ko.observable();
	this.gradeTitle = ko.observable();
	this.sectionId = ko.observable();

	this.SubjectVOarr = ko.observableArray([]);
	this.SubjectCoSchoVOarr = ko.observableArray([]);
	this.SubjectCoCurrVOarr = ko.observableArray([]);

	/**
	 *When Subject Template is loaded
	 */
	this.afterSubjectsRender = function() {
		var selectCount = $('.floorContentScholastic.disabledSelect select').length;
		var subjectCount = self.SubjectVOarr().length;
		if (selectCount == subjectCount * 2) {
			tab4SubjectViewModel.isSubjectsRendered(true);
			tab4SubjectViewModel.applyCnageToUI("afterSubjectsRender");
		};
	};

	/**
	 *Check if there needs to add the tabs
	 */
	this.addEditTabs = function() {
		/**
		 *TODO: For adding tabs
		 */
		return;
		var tabs = $("#tabAYP1").tabs();
		var tabTitle = $('#tab_title');
		var tabTemplate = "<li><a href='#{href}'>#{label}</a></li>";
		var tabCounter = 2;

		function addTab() {
			var label = tabTitle.val() || "" + tabCounter, id = "tabs-" + tabCounter;
			var li = $(tabTemplate.replace(/#\{href\}/g, "#" + id).replace(/#\{label\}/g, label));
			var websiteframe = '<div>Content</div>';
			tabs.find(".ui-tabs-nav").append(li);
			tabs.append("<div align='center' id='" + id + "'>" + websiteframe + "</div>");
			tabs.tabs("refresh");
			tabCounter++;
		}

	};

	this.gradeTitle.TermWidth = ko.computed(function() {
		//title1+title2

		var myWidth = 100 + 130 + 331 + (rootSelfTab4.TermsData().length * 100) + (rootSelfTab4.TermsData().length * 35);
		if (myWidth < 875) {
			myWidth = 875;
		}
		myWidth = myWidth + "px";
		return myWidth;
		//return this.startDate() + " - " + this.endDate();

	}, this);

	self.deleteSubject = function(item) {
		$("#dialog-confirmSubjectDelete").dialog("open");
		$("#dialog-confirmSubjectDelete #delete").click(function() {
			$("#dialog-confirmSubjectDelete").dialog("close");
			self.SubjectVOarr.remove(item);
		});
		$("#dialog-confirmSubjectDelete #cencel").click(function() {
			$("#dialog-confirmSubjectDelete").dialog("close");
		});
	};

	self.cache = function() {
	};
	//populate our model with the initial data
	self.update(data, mode);

	/**
	 * Check if the Scholastic and Non_scholastic are ready for save.
	 *
	 */
	self.sch_SubSubjectisReadyForSave = ko.computed({
		read : function() {
			var resultReturn = true;
			/**
			 *Check if there is only one subsubject
			 * then invalid it.
			 */
			ko.utils.arrayForEach(this.SubjectVOarr(), function(item) {
				//If any subject is checked :: true

				//console.log("item :: ", item)childSubs
				//console.log("item.childSubs().length :: ", item.childSubs().length);
				if (item.childSubs().length == 1) {

					resultReturn = false;
					;
				}
			});

			return resultReturn;
		},
		deferEvaluation : true //don’t evaluate until someone requests the value
	}, this);

	self.sch_isMarksValidated = ko.computed({
		read : function() {
			var isMarksValid = true;
			for (var i = 0; i < this.SubjectVOarr().length; i++) {
				var parentSub = this.SubjectVOarr()[i];

				for (var pt = 0; pt < parentSub.terms().length; pt++) {
					var pterm = parentSub.terms()[pt];
					if (pterm.marks() <= 0) {
						//break it as exception found
						isMarksValid = false;
						console.log("sch_isMarksValidated isMarksValid pterm:: ", isMarksValid);
						return isMarksValid;
					};
				};

				for (var j = 0; j < parentSub.childSubs().length; j++) {
					var childSub = parentSub.childSubs()[j];
					for (var t = 0; t < childSub.terms().length; t++) {
						var term = childSub.terms()[t];
						if (term.marks() <= 0) {
							//break it as exception found
							isMarksValid = false;
							console.log("sch_isMarksValidated isMarksValid term:: ", isMarksValid);
							return isMarksValid;
						};
					};
				};

			};
			console.log("sch_isMarksValidated isMarksValid :: ", isMarksValid);
			return isMarksValid;
		},
		deferEvaluation : true //don’t evaluate until someone requests the value
	}, this);

	self.sch_hasDuplicateSubjects = ko.computed({
		read : function() {
			var allSubjectIDArray = new Array();
			var hasDuplicate = false;
			for (var i = 0; i < this.SubjectVOarr().length; i++) {
				var parentSub = this.SubjectVOarr()[i];
				//push parent sub id
				allSubjectIDArray.push(parentSub.subjectId());
				for (var j = 0; j < parentSub.childSubs().length; j++) {
					var childSub = parentSub.childSubs()[j];
					//push child sub id
					allSubjectIDArray.push(childSub.subjectId());
				};

			};

			var uniqueSubjectIDArray = allSubjectIDArray.sort();
			// You can define the comparing function here.
			// JS by default uses a crappy string compare.
			var results = [];
			for (var u = 0; u < uniqueSubjectIDArray.length - 1; u++) {
				if (uniqueSubjectIDArray[u + 1] == uniqueSubjectIDArray[u]) {
					results.push(uniqueSubjectIDArray[u]);
				}
			}

			if (results.length) {
				hasDuplicate = true;
			};

			return hasDuplicate;
		},
		deferEvaluation : true //don’t evaluate until someone requests the value
	}, this);

	self.sch_isReadyForSave = ko.computed({
		read : function() {
			var resultReturn = false;
			/**
			 * If any subject is there :: true
			 */
			//console.log("this.SubjectVOarr.length :: ", this.SubjectVOarr().length);
			if (this.SubjectVOarr().length > 0) {
				resultReturn = true;
			}

			return resultReturn;
		},
		deferEvaluation : true //don’t evaluate until someone requests the value
	}, this);

	/**
	 * Check if 2 optionals are there in 3A and 3B
	 *
	 * only 1 optional Subject Cannot be there.
	 *
	 */
	self.cosCurrOptional_isReadyForSave = ko.computed(function() {
		var resultReturn = true;

		for (var i = 0; i < self.SubjectCoCurrVOarr().length; i++) {
			var sub = self.SubjectCoCurrVOarr()[i];
			if (sub.isOptional.showMessage()) {
				resultReturn = false;
			};
		};
		console.log("cosCurrOptional_isReadyForSave resultReturn :: ", resultReturn);
		return resultReturn;
	});

	self.coSch_isReadyForSave = ko.computed(function() {
		var resultReturn = false;
		if (self.SubjectCoSchoVOarr().length == 0) {
			resultReturn = true;
		}
		for (var i = 0; i < self.SubjectCoSchoVOarr().length; i++) {
			var sub = self.SubjectCoSchoVOarr()[i];
			for (var j = 0; j < sub.childs().length; j++) {
				var subSub = sub.childs()[j];
				//console.log("subSub.isMapped() :: ", subSub.isMapped());
				if (subSub.isMapped()) {
					resultReturn = true;
					break;
				};
			};
		};
		//console.log("resultReturn :: ", resultReturn);
		return resultReturn;
	});

};

ko.utils.extend(GradeVO.prototype, {
	update : function(data, mode) {
		//console.log("data.startDate :: " , data.startDate)
		//console.log("data.SubjectVOarr :: " , data.SubjectVOarr)
		this.ceGradeId(data.ceGradeId || "");
		this.coScholastics(data.coScholastics || "");
		this.coCurriculars(data.coCurriculars || "");
		this.coreSubjects(data.coreSubjects || "");
		this.optionalSubjects(data.optionalSubjects || '');
		this.gradeTitle(data.gradeTitle || '');
		this.sectionId(data.sectionId || '');
		//console.log("data.SubjectVOarr :: ", data.SubjectVOarr)
		//Done Mapping of Subject VO Arr
		var mappedData;
		if (data.SubjectVOarr) {
			mappedData = jQuery.map(data.SubjectVOarr, function(item) {
				return item;
			});
			this.SubjectVOarr = ko.observableArray(mappedData);
		}

		if (data.SubjectCoSchoVOarr) {
			mappedData = jQuery.map(data.SubjectCoSchoVOarr, function(item) {
				return item;
			});
			this.SubjectCoSchoVOarr = ko.observableArray(mappedData);
		}

		if (data.SubjectCoCurrVOarr) {
			mappedData = jQuery.map(data.SubjectCoCurrVOarr, function(item) {
				return item;
			});
			this.SubjectCoCurrVOarr = ko.observableArray(mappedData);
		}
		//just make it empty for DefineMode
		if (data.optionalSubjects == '' || data.coreSubjects == '') {
			//this.SubjectVOarr = ko.observableArray([]);
		}

		/*
		 no need of mapping
		 TODO: Need to repushed after creation of a new Grade VO
		 on Define
		 or may not be needed as all Grades will be created first
		 */
		if (data.SubjectListVOarr) {
			this.SubjectListVOarr(data.SubjectListVOarr);
		}
		//save off the latest data for later use
		this.cache.latestData = data;
	},

	addSubject : function(item) {
		//console.log("add Subject GradeVO:: ", item)
		myTab4Mode = "addSubjectMode";

		var itemToAdd = new SubjectVO(ko.toJS(item), myTab4Mode);

		itemToAdd.ceGradeId(item.ceGradeId());

		//console.log("itemToAdd.subjectId :: ", itemToAdd.subjectId())
		//console.log("itemToAdd.parentSubId :: ", itemToAdd.parentSubId())
		this.SubjectVOarr.push(itemToAdd);
	},

	revert : function() {
		this.update(this.cache.latestData, "");
	}
});

var childSubsData = [{
	"ceGradeId" : "",
	"sectionId" : "",
	"subjectId" : "",
	"subjectType" : 1,
	"parentSubId" : "",
	"isOptional" : 1,
	"childSubs" : [],
	"terms" : []
}];

var SubjectVOData = [{
	"ceGradeId" : "",
	"sectionId" : "",
	"subjectId" : "",
	"subjectType" : 1,
	"parentSubId" : "",
	"isOptional" : 1,
	"childSubs" : [],
	"terms" : []
}];
var rootSelfTab4;
var SubjectListVO = function(data, mode) {
	var self = this;

	this.status = ko.observable();
	this.title = ko.observable();
	this.mapping = ko.observable();
	this.subuid = ko.observable();
	this.hasGames = ko.observable();

	self.cache = function() {
	};
	//populate our model with the initial data
	self.update(data, mode);
};

ko.utils.extend(SubjectListVO.prototype, {
	update : function(data, mode) {
		this.status(data.status || "1");
		this.title(data.title || "");
		this.mapping(data.mapping || "");
		this.subuid(data.subuid || '');
		this.hasGames(data.hasGames || '');

		//save off the latest data for later use
		this.cache.latestData = data;
	},
	revert : function() {
		this.update(this.cache.latestData, "");
	}
});

var SubjectVO = function(data, mode, forMapping) {

	var self = this;
	this.ceGradeId = ko.observable();
	this.sectionId = ko.observable();
	this.subjectId = ko.observable();
	this.subjectType = ko.observable();
	this.parentSubId = ko.observable();
	this.isOptional = ko.observable();

	this.terms = ko.observableArray([]);
	this.childSubs = ko.observableArray([]);

	self.isOptional.subscribe(function(newValue) {

		var isParentSubjectOptional = newValue;
		ko.utils.arrayForEach(this.childSubs(), function(item) {
			item.isOptional(isParentSubjectOptional);
			//console.log("item.isOptional() :: ", item.isOptional());
		});
	}, this);

	self.subjectId.subjectName = ko.computed(function() {
		var subjectName = "";
		for (var i = 0; i < rootSelfTab4.SubjectListVOarr().length; i++) {
			var subjectVO = rootSelfTab4.SubjectListVOarr()[i];

			if (subjectVO.subuid() == self.subjectId()) {
				subjectName = subjectVO.title();
				break;
			};

		};
		console.log("subjectName:: ", subjectName);
		return subjectName;
	});
	self.terms.totalMarks = ko.computed(function() {

		var termTotalMaksArray = new Array();
		var currentTermTotalMaks = 0;
		var currentIndexPos = 0;

		ko.utils.arrayForEach(self.childSubs(), function(item) {

			//loop for all terms
			for (var t = 0; t < TermsData.length; t++) {
				currentTermTotalMaks = 0;
				//loop for All Subjects
				for (var s = 0; s < self.childSubs().length; s++) {
					var sub = self.childSubs()[s];
					var term = sub.terms()[t];
					var termMark = 0;
					if (term) {
						termMark = term.marks();
					};
					//console.log("termMark :: ", termMark)
					if (!termTotalMaksArray[t]) {
						termTotalMaksArray[t] = 0;
					}
					//console.log("termTotalMaksArray[t] :: ", termTotalMaksArray[t])
					currentTermTotalMaks += Number(termMark);
				};
				termTotalMaksArray[t] = currentTermTotalMaks;
			};
		});
		return termTotalMaksArray;
	});

	self.onkeypressed = function(marks, param2, param3) {
		console.log("onkeypressed marks ========== :: ", marks);
		console.log("onkeypressed param2 ========== :: ", param2);
		console.log("onkeypressed param3 ========== :: ", param3);
		//console.log("onkeypressed marks childSubs ========== :: ", marks.childSubs());
		//console.log("onkeypressed self.childSubs() ========== :: ", self.childSubs());

	};
	self.deleteSubSubject = function(item) {
		$("#dialog-confirmSubjectDelete").dialog("open");
		$("#dialog-confirmSubjectDelete #delete").click(function() {
			$("#dialog-confirmSubjectDelete").dialog("close");
			self.childSubs.remove(item);
		});
		$("#dialog-confirmSubjectDelete #cencel").click(function() {
			$("#dialog-confirmSubjectDelete").dialog("close");
		});
	};

	self.subjectId.subscribe(function(newValue) {
		//run your update code here
		//console.log("subjectId.subscribe >> newValue :: ", newValue);
		//	rootSelfTab4.UsedSubjectArray
		//SubjectVOarr
		rootSelfTab4.UsedSubjectArray([]);
		ko.utils.arrayForEach(rootSelfTab4.selectedGradeVO().SubjectVOarr(), function(item) {
			/**
			 * If any subject is checked :: true
			 */
			//console.log("item :: ", item);
			rootSelfTab4.UsedSubjectArray.push(item.subjectId());

		});
		//console.log("rootSelfTab4.UsedSubjectArray :: ", rootSelfTab4.UsedSubjectArray);
	}, this);

	self.onSubjectChange = function(option, item) {

	};

	self.cache = function() {
	};
	//populate our model with the initial data
	self.update(data, mode, forMapping);
};

ko.utils.extend(SubjectVO.prototype, {
	update : function(data, mode, forMapping) {
		//console.log("data.startDate :: " , data.startDate)
		console.log("rootSelfTab4.itemForEditing().ceGradeId() :: ", rootSelfTab4.itemForEditing().ceGradeId());

		//schgrd-656d89d2-1f1d-4794-bfe4-ccd9e666f78a class 9
		//schgrd-656d89d2-1f1d-4794-bfe4-ccd9e666f78a
		console.log("SubjectVO.prototype >> data.ceGradeId :: ", data.ceGradeId);
		console.log("SubjectVO.prototype >> this.ceGradeId() :: ", this.ceGradeId());

		if (forMapping) {
			this.ceGradeId(rootSelfTab4.itemForEditing().ceGradeId() || "");
			this.sectionId(rootSelfTab4.itemForEditing().sectionId() || sectionId);
			console.log("came in for mapping true in SubjectVO.prototype :: ");
		} else {
			this.ceGradeId(data.ceGradeId || "");
			this.sectionId(data.sectionId || sectionId);
		}

		this.subjectId(data.subjectId || "");
		this.subjectType(data.subjectType || 1);
		this.parentSubId(data.parentSubId || '');
		this.isOptional(data.isOptional || false);

		if (data.childSubs) {
			if (data.childSubs.length > 0) {
				console.log("this.isOptional parent:: ", this.isOptional());
			} else {
				console.log("this.isOptional child:: ", this.isOptional());

			}
		} else {
			console.log("else  >>> .isOptional parent:: ", this.isOptional());
		}

		//console.log("data.ceGradeId :: ", data.ceGradeId)
		//else if (mode == "addSubSubjectMode" || mode == "addSubjectMode")
		var tempMappedData;
		console.log("SubjectVO.prototype mode :: ", mode);
		if (mode == "save") {
			//also update the terms array as it is if it is in editmode
			this.terms(data.terms);
		} else if (mode == "addSubSubjectMode" || mode == "addSubjectMode") {
			// for new it will be also there.
			tempMappedData = jQuery.map(ko.toJS(TermsData), function(item) {
				//2 new term
				return new myTermVO(item);
			});
			this.terms(tempMappedData);

			// for new it will be undefined.
			if (data.childSubs) {
				tempMappedData = jQuery.map(ko.toJS(data.childSubs), function(item) {
					//SubjectVO new 2
					return new SubjectVO(item, "", forMapping);
				});
				this.childSubs(tempMappedData);
			}

		} else {

			/**
			 * Check for mapping condition as
			 * if it is mapping the terms will be taken from original Grade which is previously loaded.
			 */
			if (forMapping) {

				// for new it will be also there.
				tempMappedData = jQuery.map(ko.toJS(TermsData), function(item) {
					//3 new term
					return new myTermVO(item, forMapping);
				});

			} else {
				// for new it will be also there.
				tempMappedData = jQuery.map(data.terms, function(item) {
					//3 new term
					return new myTermVO(item);
				});

			};

			this.terms(tempMappedData);

			// for new it will be undefined.
			if (data.childSubs) {
				tempMappedData = jQuery.map(data.childSubs, function(item) {
					//SubjectVO new 3
					return new SubjectVO(item, "", forMapping);
				});
				this.childSubs(tempMappedData);
				/**
				 *Commented as it will be already sorted from Server Side
				 */
				//this.childSubs.sort(mySubjectCompareFunction);
			}

		}
		//save off the latest data for later use
		this.cache.latestData = data;
	},
	addSubSubject : function(item) {
		//console.log("addSubSubject Subject VO:: ",item)
		myTab4Mode = "addSubSubjectMode";

		var itemToAdd = new SubjectVO(ko.toJS(item), myTab4Mode);
		itemToAdd.parentSubId(item.subjectId());

		//console.log("itemToAdd.isOptional 11 :: ", itemToAdd.isOptional());
		//itemToAdd.isOptional(this.isOptional());

		//console.log("itemToAdd.isOptional 22 :: ", itemToAdd.isOptional());
		//console.log("itemToAdd.parentSubId :: ", itemToAdd.parentSubId());
		this.childSubs.push(itemToAdd);
	},

	revert : function() {
		this.update(this.cache.latestData, "");
	}
});

function loadImage() {
	console.log("loadImage :: ");
	//alert("Image is loaded");
}